/**************************************************************************
*   Copyleft 2009 by        											  *
*	Iwanicki Krzysztof													  *
*   <www.gamma.mini.pw.edu.pl/~iwanickik>		                          *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
*   This program is distributed in the hope that it will be useful,       *
*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
*   GNU General Public License for more details.                          *
***************************************************************************/
#include "./vSettings.h"
#include <iostream>
#include <fstream>

namespace Vendetta {
	vSettings::vSettings() {
	
	}
	
	vSettings::~vSettings() {
		mSections.Clear();
	}

	vVoid vSettings::LoadFromFile(const vString& fileName) {
		std::ifstream isFile;
		vString strLine, currentSection = "Default";

		isFile.open(fileName.ToConstCharPtr());
		if (isFile.exceptions() != std::ios_base::goodbit || !isFile.is_open()) {
			throw vException("Can't open file: \"%s\".  In vSettings::LoadFromFile.", fileName.ToConstCharPtr());
		}

		while (isFile.good()) {
			try {
			GetLine(isFile, strLine);
			currentSection = readLine(strLine, currentSection);
			} catch (const vException& e) {
				throw e;
			}
		}

		isFile.close();
	}

	const vString vSettings::readLine(const vString& strLine, const vString& currentSection) {
		vString ret = vStringTokenizer::EraseLeadingTailingCharacters(strLine, ' '), 
			section = currentSection;

		if (ret.Length() > 0) {
			if (ret[0] == '#' || ret[0] == ';' || ret[0] == '@') {
				return section;
			} else if (ret[0] == '[' && ret[ret.Length() - 1] == ']') {
				if (ret.Length() > 2) {
					section = ret.SubString(1, ret.Length() - 2);
					if (mSections.Contains(section)) {
						throw vException("Section with name: \"%s\" already exist. In vSettings::readLine.", 
							currentSection.ToConstCharPtr());
					}
					mSections[section] = vStringMap();
				} else {
					throw vException("Wrong file format, empty section name. In vSettings::readLine.");
				}
			} else {
				vArray<vString> keyVal = vStringTokenizer::Split(ret, "=\t:");
				vString val, key;

				if (keyVal.Size() == 2 && !keyVal[0].IsEmpty() &&!keyVal[1].IsEmpty()) {
					key = vStringTokenizer::EraseLeadingTailingCharacters(keyVal[0], ' ');
					val = vStringTokenizer::EraseLeadingTailingCharacters(keyVal[1], ' ');
					if (key.IsEmpty() || val.IsEmpty()) {
						throw vException("Wrong file format, key or value are null. In vSettings::readLine");
					}
				} else {
					throw vException("Wrong file format, key or value are null. In vSettings::readLine.");
				}
				
				mSections[currentSection]<<vPair<vString, vString>(key, val);
			}
		}

		return section;
	}

	const vString& vSettings::Setting(const vString& name, const vString& section) {
		if (!mSections.Contains(section)) {
			throw vException("Section with name \"%s\" does not exists. In vSettings::Setting.", 
				section.ToConstCharPtr());
		}
		if (!mSections[section].Contains(name)) {
			throw vException("Setting with name \"%s\" does not exists in \"%s\" section. In vSettings::Setting.", 
				name.ToConstCharPtr(), section.ToConstCharPtr());
		}
		
		return mSections[section][name];
	}

	const vHashMap<vString, vString>& vSettings::Settings(const vString& section) {
		if (!mSections.Contains(section)) {
			throw vException("Section with name \"%s\" does not exists. In vSettings::Settings.", 
				section.ToConstCharPtr());
		}

		return mSections[section];
	}
}